/*
 * hash.h
 *
 *  Created on: 2012-8-12
 *      Author: lin
 */

#ifndef HASH_H_
#define HASH_H_

#include "defs.h"
/* Thomas Wang's 32 bit Mix Function */
static inline uint32_t hash_uint32(uint32_t key) {
    key += ~(key << 15);
    key ^= (key >> 10);
    key += (key << 3);
    key ^= (key >> 6);
    key += ~(key << 11);
    key ^= (key >> 16);
    return key;
}

/* Identity hash function for integer keys */
static inline uint32_t hash_identity_uint32(uint32_t key) {
    return key;
}

/*from java Long*/
static inline uint32_t hash_uint64(uint64_t key) {
    uint64_t low = key >> 32;
    return (uint32_t) key ^ low;
}

static inline uint32_t hash_identity_uint64(uint64_t key) {
    return (uint32_t) key;
}

/* Generic hash function (a popular one from Bernstein).*/
static inline uint32_t hash_nstring(const unsigned char *buf, int32_t len) {
    uint32_t hash = 5381;

    while (len--)
        hash = ((hash << 5) + hash) + (*buf++); /* hash * 33 + c */
    return hash;
}

static inline uint32_t hash_string(const unsigned char *buf) {
    return hash_nstring(buf, strlen(buf));
}

/* And a case insensitive version */
static inline uint32_t dictGenCaseHashFunction(const unsigned char *buf,
        int32_t len) {
    uint32_t hash = 5381;

    while (len--)
        hash = ((hash << 5) + hash) + (tolower(*buf++)); /* hash * 33 + c */
    return hash;
}
static inline uint32_t mixed_t_hash_string(const mixed_t key) {
    return hash_string(key.ptr);
}

#endif /* HASH_H_ */
